home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / tex / dvi / dvipssrc.zoo / output.c < prev    next >
C/C++ Source or Header  |  1991-01-26  |  14KB  |  620 lines

  1. /*
  2.  *   These routines do most of the communicating with the printer.
  3.  *
  4.  *   LINELENGTH tells the maximum line length to send out.
  5.  */
  6. #define LINELENGTH (78)
  7. #include "structures.h" /* The copyright notice in that file is included too! */
  8. #include <ctype.h>
  9. /*
  10.  *   The external routines called here:
  11.  */
  12. extern void error() ;
  13. extern void send_headers() ;
  14. extern FILE *search() ;
  15. extern char *getenv() ;
  16. extern void fonttableout() ;
  17. extern void makepsname() ;
  18. /*
  19.  *   These are the external variables used by these routines.
  20.  */
  21. extern integer hh, vv ;
  22. extern fontdesctype *curfnt ;
  23. extern FILE *bitfile ;
  24. extern char *oname ;
  25. extern Boolean reverse ;
  26. extern Boolean removecomments ;
  27. extern Boolean sendcontrolD, disablecomments, multiplesects ;
  28. extern Boolean usesPSfonts, headers_off ;
  29. extern Boolean safetyenclose ;
  30. extern int numcopies ;
  31. extern int totalpages ;
  32. extern integer pagenum ;
  33. extern Boolean manualfeed ;
  34. extern int landscape ;
  35. extern int quiet ;
  36. extern int prettycolumn ;
  37. extern int actualdpi ;
  38. extern char *iname ;
  39. extern char *paperfmt ;
  40. extern char *headerpath ;
  41. extern char errbuf[] ;
  42. extern shalfword linepos ;
  43. extern char *figpath ;
  44. extern struct header_list *ps_fonts_used ;
  45. extern char banner[] ;
  46. /*
  47.  *   We need a few statics to take care of things.
  48.  */
  49. static integer rhh, rvv ;
  50. static int instring ;
  51. static Boolean lastspecial = 1 ;
  52. static shalfword d ;
  53. static Boolean popened = 0 ;
  54. int lastfont ; /* exported to dospecial to fix rotate.tex problem */
  55. static void chrcmd();                   /* just a forward declaration */
  56. static char strbuffer[LINELENGTH + 20], *strbp = strbuffer ;
  57. static struct {
  58.     char *format;
  59.     int width, height;
  60. } paper_types[] = {
  61.     { "letter",  612,  792 },        /* 8.5 x 11 */
  62.     { "legal",   612, 1008 },        /* 8.5 x 14 */
  63.     { "ledger",  792, 1224 },        /* 11 x 17 */
  64.     { "a4",     596,  843 },        /* 210mm x 297mm */
  65.     { "a3",      843, 1192 } };        /* 297mm x 420mm */
  66. /*
  67.  *   This routine copies a file down the pipe.  Search path uses the
  68.  *   header path.
  69.  */
  70. static int infigure ;
  71. void
  72. copyfile(s)
  73.         char *s ;
  74. {
  75.    FILE *f = NULL ;
  76.    int c, prevc = '\n' ;
  77.  
  78.    switch (infigure) {
  79.    case 1:
  80.       f = search(figpath, s, READ) ;
  81.       (void)sprintf(errbuf, "Couldn't find figure file %s; continuing", s) ;
  82.       break ;
  83.    default:
  84.       f = search(headerpath, s, READ) ;
  85.       (void)sprintf(errbuf, "! Couldn't find header file %s", s) ;
  86.       break ;
  87. #ifndef VMS
  88. #ifndef MSDOS
  89.    case 2:
  90. #ifdef SECURE
  91.       (void)sprintf(errbuf, "<%s>: Tick filename execution disabled", s) ;
  92. #else
  93.       f = popen(s, "r") ;
  94.       (void)sprintf(errbuf, "Failure to execute %s; continuing", s) ;
  95. #endif
  96.       break;
  97. #endif
  98. #endif
  99.    }
  100.    if (f==NULL)
  101.       error(errbuf) ;
  102.    else {
  103.       if (! quiet) {
  104.          if (strlen(s) + prettycolumn > 76) {
  105.             fprintf(stderr, "\n") ;
  106.             prettycolumn = 0 ;
  107.          }
  108.          (void)fprintf(stderr, "<%s>", s) ;
  109.          (void)fflush(stderr) ;
  110.          prettycolumn += 2 + strlen(s) ;
  111.       }
  112.       if (linepos != 0)
  113.          (void)putc('\n', bitfile) ;
  114.       if (! disablecomments)
  115.          if (infigure)
  116.             (void)fprintf(bitfile, "%%%%BeginDocument: %s\n", s) ;
  117.          else
  118.             (void)fprintf(bitfile, "%%%%BeginProcSet: %s\n", s) ;
  119.       while ((c=getc(f))!=EOF && c != 4) {
  120.          if (removecomments && c == '%' && prevc == '\n') {/* skip comments */
  121.             while ((c=getc(f))!=EOF) {
  122.                if (c=='\n')
  123.                   break ;
  124.             }
  125.          } else
  126.             (void)putc(c, bitfile) ;
  127.          prevc = c ;
  128.       }
  129.       if (prevc != '\n')
  130.          (void)putc('\n', bitfile) ;
  131.       linepos = 0 ;
  132. #ifndef VMS
  133. #ifndef MSDOS
  134.       if (infigure == 2)
  135.          (void)pclose(f) ;
  136.       else
  137. #endif
  138. #endif
  139.          (void)fclose(f) ;
  140.       if (!disablecomments)
  141.          if (infigure)
  142.             (void)fprintf(bitfile, "%%%%EndDocument\n") ;
  143.          else
  144.             (void)fprintf(bitfile, "%%%%EndProcSet\n") ;
  145.    }
  146. }
  147.  
  148. /*
  149.  *   For included PostScript graphics, we use the above routine, but
  150.  *   with no fatal error message.
  151.  */
  152. void figcopyfile(s, systemtype)
  153. char *s ;
  154. int systemtype ;
  155. {
  156.    infigure = systemtype ? 2 : 1 ;
  157.    copyfile(s) ;
  158.    infigure = 0 ;
  159. }
  160.  
  161. /*
  162.  *   This next routine writes out a `special' character.  In this case,
  163.  *   we simply put it out, since any special character terminates the
  164.  *   preceding token.
  165.  */
  166. void
  167. specialout(c)
  168.         char c ;
  169. {
  170.    if (linepos >= LINELENGTH) {
  171.       (void)putc('\n', bitfile) ;
  172.       linepos = 0 ;
  173.    }
  174.    (void)putc(c, bitfile) ;
  175.    linepos++ ;
  176.    lastspecial = 1 ;
  177. }
  178.  
  179. void
  180. stringend()
  181. {
  182.    if (linepos + instring >= LINELENGTH - 2) {
  183.       (void)putc('\n', bitfile) ;
  184.       linepos = 0 ;
  185.    }
  186.    (void)putc('(', bitfile) ;
  187.    *strbp = 0 ;
  188.    (void)fputs(strbuffer, bitfile) ;
  189.    (void)putc(')', bitfile) ;
  190.    linepos += instring + 2 ;
  191.    lastspecial = 1 ;
  192.    instring = 0 ;
  193.    strbp = strbuffer ;
  194. }
  195.  
  196. void
  197. scout(c)   /* string character out */
  198.         char c ;
  199. {
  200. /*
  201.  *   Is there room in the buffer?  LINELENGTH-6 is used because we
  202.  *   need room for (, ), and a possible four-byte string \000, for
  203.  *   instance.  If it is too long, we send out the string.
  204.  */
  205.    if (instring > LINELENGTH-6) {
  206.       stringend() ;
  207.       chrcmd('p') ;
  208.    }
  209.    if (c<' ' || c>126 || c=='%') {
  210.       *strbp++ = '\\' ;
  211.       *strbp++ = '0' + ((c >> 6) & 3) ;
  212.       *strbp++ = '0' + ((c >> 3) & 7) ;
  213.       *strbp++ = '0' + (c & 7) ;
  214.       instring += 4 ;
  215.    } else if (c == '(' || c == ')' || c == '\\') {
  216.       *strbp++ = '\\' ;
  217.       *strbp++ = c ;
  218.       instring += 2 ;
  219.    } else {
  220.       *strbp++ = c ;
  221.       instring++ ;
  222.    }
  223. }
  224.  
  225. void
  226. cmdout(s)
  227.         char *s ;
  228. {
  229.    int l ;
  230.  
  231.    /* hack added by dorab */
  232.    if (instring) {
  233.         stringend();
  234.         chrcmd('p');
  235.    }
  236.    l = strlen(s) ;
  237.    if ((! lastspecial && linepos >= LINELENGTH - 20) ||
  238.            linepos + l >= LINELENGTH) {
  239.       (void)putc('\n', bitfile) ;
  240.       linepos = 0 ;
  241.       lastspecial = 1 ;
  242.    } else if (! lastspecial) {
  243.       (void)putc(' ', bitfile) ;
  244.       linepos++ ;
  245.    }
  246.    (void)fputs(s, bitfile) ;
  247.    linepos += l ;
  248.    lastspecial = 0 ;
  249. }
  250.  
  251.  
  252. static void
  253. chrcmd(c)
  254.         char c ;
  255. {
  256.    if ((! lastspecial && linepos >= LINELENGTH - 20) ||
  257.        linepos + 2 > LINELENGTH) {
  258.       (void)putc('\n', bitfile) ;
  259.       linepos = 0 ;
  260.       lastspecial = 1 ;
  261.    } else if (! lastspecial) {
  262.       (void)putc(' ', bitfile) ;
  263.       linepos++ ;
  264.    }
  265.    (void)putc(c, bitfile) ;
  266.    linepos++ ;
  267.    lastspecial = 0 ;
  268. }
  269.  
  270. void
  271. floatout(n)
  272.         float n ;
  273. {
  274.    char buf[20] ;
  275.  
  276.    (void)sprintf(buf, "%.2f", n) ;
  277.    cmdout(buf) ;
  278. }
  279.  
  280. void
  281. numout(n)
  282.         integer n ;
  283. {
  284.    char buf[10] ;
  285.  
  286.    (void)sprintf(buf, "%ld", n) ;
  287.    cmdout(buf) ;
  288. }
  289.  
  290. void
  291. mhexout(p, len)
  292. register unsigned char *p ;
  293. register long len ;
  294. {
  295.    register char *hexchar = "0123456789ABCDEF" ;
  296.    register int n, k ;
  297.  
  298.    while (len > 0) {
  299.       if (linepos > LINELENGTH - 2) {
  300.          (void)putc('\n', bitfile) ;
  301.          linepos = 0 ;
  302.       }
  303.       k = (LINELENGTH - linepos) >> 1 ;
  304.       if (k > len)
  305.          k = len ;
  306.       len -= k ;
  307.       linepos += (k << 1) ;
  308.       while (k--) {
  309.          n = *p++ ;
  310.          (void)putc(hexchar[n >> 4], bitfile) ;
  311.          (void)putc(hexchar[n & 15], bitfile) ;
  312.       }
  313.    }
  314. }
  315.  
  316. void
  317. fontout(n)
  318.         int n ;
  319. {
  320.    char buf[6] ;
  321.  
  322.    if (instring) {
  323.       stringend() ;
  324.       chrcmd('p') ;
  325.    }
  326.    makepsname(buf, n) ;
  327.    cmdout(buf) ;
  328. }
  329.  
  330. void
  331. hvpos()
  332. {
  333.    if (rvv != vv) {
  334.       if (instring) {
  335.          stringend() ;
  336.          numout(hh) ;
  337.          numout(vv) ;
  338.          chrcmd('y') ;
  339.       } else if (rhh != hh) {
  340.          numout(hh) ;
  341.          numout(vv) ;
  342.          chrcmd('a') ;
  343.       } else { /* hard to get this case, but it's there when you need it! */
  344.          numout(vv - rvv) ;
  345.          chrcmd('x') ;
  346.       }
  347.       rvv = vv ;
  348.    } else if (rhh != hh) {
  349.       if (instring) {
  350.          stringend() ;
  351.          if (hh - rhh < 5 && rhh - hh < 5) {
  352.             chrcmd((char)('p' + hh - rhh)) ;
  353.          } else if (hh - rhh < d + 5 && rhh - hh < 5 - d) {
  354.             chrcmd((char)('g' + hh - rhh - d)) ;
  355.             d = hh - rhh ;
  356.          } else {
  357.             numout(hh - rhh) ;
  358.             chrcmd('b') ;
  359.